package com.darwin.darwinBitmapEngine.view
{
	import com.darwin.darwinBitmapEngine.core.Canvas;
	import com.darwin.darwinIsometric.core.IsoWorld;
	
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	/**
	 * 场景视图。最终将可见对象加到舞台的类。
	 * @author lipi&vanCopper
	 */
	public class SceneView
	{
		//TODO 当鼠标在UI层或者面板层时 由于鼠标层在这些层下面 所以鼠标事件是无法感应的
		public var isoWorld:IsoWorld;
		
		private var _isAbleDrag:Boolean = true;
		public function SceneView(stage:Stage)
		{
			super();
			this.stage = stage;
			init();
		}
		
		private function init():void
		{
			_sprite = new Sprite();
			_sprite.mouseEnabled = false;
			_sprite.mouseChildren = false;
			stage.addChildAt(_sprite,0);
//			stage.addChild(_sprite);
			
			_mouseLayer = new Sprite();
			_mouseLayer.mouseChildren = false;
			stage.addChildAt(_mouseLayer,1);
			
			var sp:Shape = new Shape();
			sp.graphics.beginFill(0x00FF00,0);
			sp.graphics.drawRect(0,0,1,1);
			sp.graphics.endFill();
			_mouseLayer.addChild(sp);
			onStageResize();
			
			_mouseLayer.addEventListener(MouseEvent.CLICK,mouseEventHandler);
			_mouseLayer.addEventListener(MouseEvent.MOUSE_MOVE,mouseEventHandler);
			_mouseLayer.addEventListener(MouseEvent.MOUSE_OUT,mouseEventHandler);
			_mouseLayer.addEventListener(MouseEvent.MOUSE_DOWN,mouseEventHandler);
			_mouseLayer.addEventListener(MouseEvent.MOUSE_UP,mouseEventHandler);
			//无奈的监听
			stage.addEventListener(MouseEvent.MOUSE_UP,onStageMouseUp);
			stage.addEventListener(Event.RESIZE,onStageResize);
		}
		
		/**
		 * 当鼠标放开时 
		 * @param e
		 * 
		 */		
		private function onStageMouseUp(e:MouseEvent):void
		{
			_isMouseDown = false;
		}
		
		protected function onStageResize(event:Event = null):void
		{
			_mouseLayer.width = this.stage.stageWidth;
			_mouseLayer.height = this.stage.stageHeight;
		}
		
		private var _usePreciseClick:Boolean = false;
		/**
		 * 使用精确的鼠标点击事件。
		 * 用户在点击场景时有一定概率发生微小移动，导致操作变成拖拽屏幕而不是点击，
		 * 这个参数为false时，将把这种微小移动当做单击事件处理。设置true禁用此功能。
		 */
		public function get usePreciseClick():Boolean
		{
			return _usePreciseClick;
		}

		public function set usePreciseClick(value:Boolean):void
		{
			_usePreciseClick = value;
		}

		
		//鼠标是否按下		
		protected var _isMouseDown:Boolean;
		protected var _prevLocalX:Number = -1;
		protected var _prevLocalY:Number = -1;
		private var _clickDis:int = 3;
		
		protected function mouseEventHandler(event:MouseEvent):void
		{
			var mouseX:Number = this.stage.mouseX;
			var mouseY:Number = this.stage.mouseY;
			if(event.type == MouseEvent.MOUSE_UP)
			{
				if((_prevLocalX == mouseX && _prevLocalY == mouseY)
					||(!_usePreciseClick
						&&(Math.abs(_prevLocalX-mouseX)<_clickDis || Math.abs(_prevLocalY-mouseY)<_clickDis)))
				{
					isoWorld.mouseEventHandler(mouseX,mouseY,MouseEvent.CLICK);
				}
			}
			
			if(event.type == MouseEvent.MOUSE_DOWN)
			{
				isoWorld.mouseEventHandler(mouseX,mouseY,event.type);
				_prevLocalX = mouseX;
				_prevLocalY = mouseY;
				_isMouseDown = true;
				isoWorld.startDrag(new Point(mouseX,mouseY));
			}else if(event.type == MouseEvent.MOUSE_MOVE)
			{
				isoWorld.mouseEventHandler(mouseX,mouseY,event.type);
				if(_isMouseDown && isAbleDrag)
				{
					isoWorld.updateDrag(new Point(mouseX,mouseY));
				}
			}else if(event.type == MouseEvent.MOUSE_UP)
			{
				isoWorld.mouseEventHandler(mouseX,mouseY,event.type);
				_isMouseDown = false;
				isoWorld.stopDrag();
			}else if(event.type == MouseEvent.MOUSE_OUT)
			{
				isoWorld.mouseEventHandler(mouseX,mouseY,event.type);
				if(!_isMouseDown)
				{
					isoWorld.stopDrag();
				}
			}
		}
		
		/**
		 * 舞台对象
		 */
		public var stage:Stage;
		
		
		private var _sprite:Sprite;
		
		/**
		 * 鼠标管理层 负责派发鼠标事件 
		 */		
		public var _mouseLayer:Sprite;
		
		
		/**
		 * 添加画布列表到舞台
		 * @param list 画布列表
		 */
		public function addCanvasList(list:Vector.<Canvas>):void
		{
			for(var i:int = 0;i<list.length;i++)
			{
				_sprite.addChild(list[i]);
			}
		}
		
		/**
		 * 清空SceneView中的显示对象
		 */
		public function clearCanvasList():void
		{
			stage.removeChild(_sprite);
			_sprite = null;
		}

		/**
		 * 世界场景是否可拖动 默认场景可拖动
		 */
		public function get isAbleDrag():Boolean
		{
			return _isAbleDrag;
		}

		/**
		 * @private
		 */
		public function set isAbleDrag(value:Boolean):void
		{
			_isAbleDrag = value;
		}

		/**
		 *	将当前场景上的内容绘制到位图上
		 * <br/>将场景上的当前内容复制到一个 BitmapData 对象。适用于截图等操作。
		 * <br/>这可能是一个非常缓慢的操作。请谨慎使用。
		 * @param bitmapData 
		 * 
		 */
		public function drawToBitmapData(bitmapData:BitmapData):void
		{
			if(bitmapData)
			{
				bitmapData.draw(_sprite);
			}
		}
	}
}